function spqr_make
%SPQR_MAKE compiles the SuiteSparseQR mexFunctions
%
% Example:
%   spqr_make
%
% SuiteSparseQR relies on CHOLMOD, AMD, and COLAMD, and optionally CCOLAMD,
% CAMD, and METIS.  Next, type
%
%   spqr_make
%
% in the MATLAB command window.  If METIS is not present in
% ../../CHOLMOD/SuiteSparse_metis, then it is not used.
%
% You must type the spqr_make command while in the SuiteSparseQR/MATLAB
% directory.
%
% See also spqr, spqr_solve, spqr_qmult, qr, mldivide

% SPQR, Copyright (c) 2008-2022, Timothy A Davis. All Rights Reserved.
% SPDX-License-Identifier: GPL-2.0+

if verLessThan ('matlab', '9.4')
    error ('MATLAB 9.4 (R2018a) or later is required') ;
end

details = 0 ;       % 1 if details of each command are to be printed, 0 if not

% TODO: after removing interleaved complex support, use these flags:
% flags = '-O -R2018a -silent ' ;
% instead of these:
flags = '-O -largeArrayDims -silent ' ;

if (ispc)
    % MSVC does not define ssize_t
    flags = [flags ' -DNO_SSIZE_T'] ;
end

include = '-DNMATRIXOPS -DNMODIFY -I. -I../../AMD/Include -I../../COLAMD/Include -I../../CHOLMOD/Include -I../Include -I../../SuiteSparse_config' ;

% Determine if METIS is available
if (exist ('../../CHOLMOD/SuiteSparse_metis', 'dir'))
    fprintf ('Compiling SPQR with METIS for MATLAB Version %s\n', version) ;
    include = [include ' -I../../CHOLMOD/SuiteSparse_metis/include'] ;
    include = [include ' -I../../CHOLMOD/SuiteSparse_metis/GKlib'] ;
    include = [include ' -I../../CHOLMOD/SuiteSparse_metis/libmetis'] ;
else
    fprintf ('Compiling SPQR without METIS for MATLAB Version %s\n', version) ;
    include = ['-DNPARTITION ' include] ;
end

include = [include ' -I../../CCOLAMD/Include -I../../CAMD/Include -I../../CHOLMOD' ] ;

%-------------------------------------------------------------------------------
% BLAS option
%-------------------------------------------------------------------------------

if (ispc)
    % BLAS/LAPACK functions have no underscore on Windows
    flags = [flags ' -DBLAS_NO_UNDERSCORE'] ;
    if (verLessThan ('matlab', '9.5'))
        lib = 'libmwlapack.lib libmwblas.lib' ;
    else
        lib = '-lmwlapack -lmwblas' ;
    end
else
    % BLAS/LAPACK functions have an underscore suffix
    flags = [flags ' -DBLAS_UNDERSCORE'] ;
    lib = '-lmwlapack -lmwblas' ;
end

flags = [flags ' -DBLAS64'] ;

if (~(ispc || ismac))
    % for POSIX timing routine
    lib = [lib ' -lrt'] ;
end

%-------------------------------------------------------------------------------

config_src = { '../../SuiteSparse_config/SuiteSparse_config' } ;

amd_c_src = { ...
    '../../AMD/Source/amd_l1', ...
    '../../AMD/Source/amd_l2', ...
    '../../AMD/Source/amd_l_aat', ...
    '../../AMD/Source/amd_l_control', ...
    '../../AMD/Source/amd_l_defaults', ...
    '../../AMD/Source/amd_l_dump', ...
    '../../AMD/Source/amd_l_info', ...
    '../../AMD/Source/amd_l_order', ...
    '../../AMD/Source/amd_l_postorder', ...
    '../../AMD/Source/amd_l_post_tree', ...
    '../../AMD/Source/amd_l_preprocess', ...
    '../../AMD/Source/amd_l_valid', ...
    '../../AMD/Source/amd_1', ...
    '../../AMD/Source/amd_2', ...
    '../../AMD/Source/amd_aat', ...
    '../../AMD/Source/amd_control', ...
    '../../AMD/Source/amd_defaults', ...
    '../../AMD/Source/amd_dump', ...
    '../../AMD/Source/amd_info', ...
    '../../AMD/Source/amd_order', ...
    '../../AMD/Source/amd_postorder', ...
    '../../AMD/Source/amd_post_tree', ...
    '../../AMD/Source/amd_preprocess', ...
    '../../AMD/Source/amd_valid' } ;

colamd_c_src = {
    '../../COLAMD/Source/colamd_l', ...
    '../../COLAMD/Source/colamd' } ;

% CAMD and CCOLAMD are not needed if we don't have METIS
camd_c_src = { ...
    '../../CAMD/Source/camd_l1', ...
    '../../CAMD/Source/camd_l2', ...
    '../../CAMD/Source/camd_l_aat', ...
    '../../CAMD/Source/camd_l_control', ...
    '../../CAMD/Source/camd_l_defaults', ...
    '../../CAMD/Source/camd_l_dump', ...
    '../../CAMD/Source/camd_l_info', ...
    '../../CAMD/Source/camd_l_order', ...
    '../../CAMD/Source/camd_l_postorder', ...
    '../../CAMD/Source/camd_l_preprocess', ...
    '../../CAMD/Source/camd_l_valid', ...
    '../../CAMD/Source/camd_1', ...
    '../../CAMD/Source/camd_2', ...
    '../../CAMD/Source/camd_aat', ...
    '../../CAMD/Source/camd_control', ...
    '../../CAMD/Source/camd_defaults', ...
    '../../CAMD/Source/camd_dump', ...
    '../../CAMD/Source/camd_info', ...
    '../../CAMD/Source/camd_order', ...
    '../../CAMD/Source/camd_postorder', ...
    '../../CAMD/Source/camd_preprocess', ...
    '../../CAMD/Source/camd_valid' } ;


ccolamd_c_src = {
    '../../CCOLAMD/Source/ccolamd_l', ...
    '../../CCOLAMD/Source/ccolamd' } ;

cholmod_c_src = {
    '../../CHOLMOD/Utility/cholmod_l_aat', ...
    '../../CHOLMOD/Utility/cholmod_l_add', ...
    '../../CHOLMOD/Utility/cholmod_l_add_size_t', ...
    '../../CHOLMOD/Utility/cholmod_l_alloc_factor', ...
    '../../CHOLMOD/Utility/cholmod_l_alloc_work', ...
    '../../CHOLMOD/Utility/cholmod_l_allocate_dense', ...
    '../../CHOLMOD/Utility/cholmod_l_allocate_factor', ...
    '../../CHOLMOD/Utility/cholmod_l_allocate_sparse', ...
    '../../CHOLMOD/Utility/cholmod_l_allocate_triplet', ...
    '../../CHOLMOD/Utility/cholmod_l_allocate_work', ...
    '../../CHOLMOD/Utility/cholmod_l_band', ...
    '../../CHOLMOD/Utility/cholmod_l_band_nnz', ...
    '../../CHOLMOD/Utility/cholmod_l_calloc', ...
    '../../CHOLMOD/Utility/cholmod_l_change_factor', ...
    '../../CHOLMOD/Utility/cholmod_l_clear_flag', ...
    '../../CHOLMOD/Utility/cholmod_l_copy', ...
    '../../CHOLMOD/Utility/cholmod_l_copy_dense', ...
    '../../CHOLMOD/Utility/cholmod_l_copy_dense2', ...
    '../../CHOLMOD/Utility/cholmod_l_copy_factor', ...
    '../../CHOLMOD/Utility/cholmod_l_copy_sparse', ...
    '../../CHOLMOD/Utility/cholmod_l_copy_triplet', ...
    '../../CHOLMOD/Utility/cholmod_l_cumsum', ...
    '../../CHOLMOD/Utility/cholmod_l_dbound', ...
    '../../CHOLMOD/Utility/cholmod_l_defaults', ...
    '../../CHOLMOD/Utility/cholmod_l_dense_nnz', ...
    '../../CHOLMOD/Utility/cholmod_l_dense_to_sparse', ...
    '../../CHOLMOD/Utility/cholmod_l_divcomplex', ...
    '../../CHOLMOD/Utility/cholmod_l_ensure_dense', ...
    '../../CHOLMOD/Utility/cholmod_l_error', ...
    '../../CHOLMOD/Utility/cholmod_l_eye', ...
    '../../CHOLMOD/Utility/cholmod_l_factor_to_sparse', ...
    '../../CHOLMOD/Utility/cholmod_l_finish', ...
    '../../CHOLMOD/Utility/cholmod_l_free', ...
    '../../CHOLMOD/Utility/cholmod_l_free_dense', ...
    '../../CHOLMOD/Utility/cholmod_l_free_factor', ...
    '../../CHOLMOD/Utility/cholmod_l_free_sparse', ...
    '../../CHOLMOD/Utility/cholmod_l_free_triplet', ...
    '../../CHOLMOD/Utility/cholmod_l_free_work', ...
    '../../CHOLMOD/Utility/cholmod_l_hypot', ...
    '../../CHOLMOD/Utility/cholmod_l_malloc', ...
    '../../CHOLMOD/Utility/cholmod_l_maxrank', ...
    '../../CHOLMOD/Utility/cholmod_l_mult_size_t', ...
    '../../CHOLMOD/Utility/cholmod_l_nnz', ...
    '../../CHOLMOD/Utility/cholmod_l_ones', ...
    '../../CHOLMOD/Utility/cholmod_l_pack_factor', ...
    '../../CHOLMOD/Utility/cholmod_l_ptranspose', ...
    '../../CHOLMOD/Utility/cholmod_l_realloc', ...
    '../../CHOLMOD/Utility/cholmod_l_realloc_multiple', ...
    '../../CHOLMOD/Utility/cholmod_l_reallocate_column', ...
    '../../CHOLMOD/Utility/cholmod_l_reallocate_factor', ...
    '../../CHOLMOD/Utility/cholmod_l_reallocate_sparse', ...
    '../../CHOLMOD/Utility/cholmod_l_reallocate_triplet', ...
    '../../CHOLMOD/Utility/cholmod_l_sbound', ...
    '../../CHOLMOD/Utility/cholmod_l_score_comp', ...
    '../../CHOLMOD/Utility/cholmod_l_set_empty', ...
    '../../CHOLMOD/Utility/cholmod_l_sort', ...
    '../../CHOLMOD/Utility/cholmod_l_sparse_to_dense', ...
    '../../CHOLMOD/Utility/cholmod_l_sparse_to_triplet', ...
    '../../CHOLMOD/Utility/cholmod_l_speye', ...
    '../../CHOLMOD/Utility/cholmod_l_spzeros', ...
    '../../CHOLMOD/Utility/cholmod_l_start', ...
    '../../CHOLMOD/Utility/cholmod_l_transpose', ...
    '../../CHOLMOD/Utility/cholmod_l_transpose_sym', ...
    '../../CHOLMOD/Utility/cholmod_l_transpose_unsym', ...
    '../../CHOLMOD/Utility/cholmod_l_triplet_to_sparse', ...
    '../../CHOLMOD/Utility/cholmod_l_version', ...
    '../../CHOLMOD/Utility/cholmod_l_xtype', ...
    '../../CHOLMOD/Utility/cholmod_l_zeros', ...
    '../../CHOLMOD/Utility/cholmod_mult_uint64_t', ...
    '../../CHOLMOD/Utility/cholmod_memdebug', ...
    '../../CHOLMOD/Check/cholmod_l_check', ...
    '../../CHOLMOD/Check/cholmod_l_read', ...
    '../../CHOLMOD/Check/cholmod_l_write', ...
    '../../CHOLMOD/Cholesky/cholmod_l_amd', ...
    '../../CHOLMOD/Cholesky/cholmod_l_analyze', ...
    '../../CHOLMOD/Cholesky/cholmod_l_colamd', ...
    '../../CHOLMOD/Cholesky/cholmod_l_etree', ...
    '../../CHOLMOD/Cholesky/cholmod_l_factorize', ...
    '../../CHOLMOD/Cholesky/cholmod_l_postorder', ...
    '../../CHOLMOD/Cholesky/cholmod_l_rcond', ...
    '../../CHOLMOD/Cholesky/cholmod_l_resymbol', ...
    '../../CHOLMOD/Cholesky/cholmod_l_rowcolcounts', ...
    '../../CHOLMOD/Cholesky/cholmod_l_rowfac', ...
    '../../CHOLMOD/Cholesky/cholmod_l_solve', ...
    '../../CHOLMOD/Cholesky/cholmod_l_spsolve', ...
    '../../CHOLMOD/Supernodal/cholmod_l_super_numeric', ...
    '../../CHOLMOD/Supernodal/cholmod_l_super_solve', ...
    '../../CHOLMOD/Supernodal/cholmod_l_super_symbolic', ...
    '../../CHOLMOD/Utility/cholmod_aat', ...
    '../../CHOLMOD/Utility/cholmod_add', ...
    '../../CHOLMOD/Utility/cholmod_add_size_t', ...
    '../../CHOLMOD/Utility/cholmod_alloc_factor', ...
    '../../CHOLMOD/Utility/cholmod_alloc_work', ...
    '../../CHOLMOD/Utility/cholmod_allocate_dense', ...
    '../../CHOLMOD/Utility/cholmod_allocate_factor', ...
    '../../CHOLMOD/Utility/cholmod_allocate_sparse', ...
    '../../CHOLMOD/Utility/cholmod_allocate_triplet', ...
    '../../CHOLMOD/Utility/cholmod_allocate_work', ...
    '../../CHOLMOD/Utility/cholmod_band', ...
    '../../CHOLMOD/Utility/cholmod_band_nnz', ...
    '../../CHOLMOD/Utility/cholmod_calloc', ...
    '../../CHOLMOD/Utility/cholmod_change_factor', ...
    '../../CHOLMOD/Utility/cholmod_clear_flag', ...
    '../../CHOLMOD/Utility/cholmod_copy', ...
    '../../CHOLMOD/Utility/cholmod_copy_dense', ...
    '../../CHOLMOD/Utility/cholmod_copy_dense2', ...
    '../../CHOLMOD/Utility/cholmod_copy_factor', ...
    '../../CHOLMOD/Utility/cholmod_copy_sparse', ...
    '../../CHOLMOD/Utility/cholmod_copy_triplet', ...
    '../../CHOLMOD/Utility/cholmod_cumsum', ...
    '../../CHOLMOD/Utility/cholmod_dbound', ...
    '../../CHOLMOD/Utility/cholmod_defaults', ...
    '../../CHOLMOD/Utility/cholmod_dense_nnz', ...
    '../../CHOLMOD/Utility/cholmod_dense_to_sparse', ...
    '../../CHOLMOD/Utility/cholmod_divcomplex', ...
    '../../CHOLMOD/Utility/cholmod_ensure_dense', ...
    '../../CHOLMOD/Utility/cholmod_error', ...
    '../../CHOLMOD/Utility/cholmod_eye', ...
    '../../CHOLMOD/Utility/cholmod_factor_to_sparse', ...
    '../../CHOLMOD/Utility/cholmod_finish', ...
    '../../CHOLMOD/Utility/cholmod_free', ...
    '../../CHOLMOD/Utility/cholmod_free_dense', ...
    '../../CHOLMOD/Utility/cholmod_free_factor', ...
    '../../CHOLMOD/Utility/cholmod_free_sparse', ...
    '../../CHOLMOD/Utility/cholmod_free_triplet', ...
    '../../CHOLMOD/Utility/cholmod_free_work', ...
    '../../CHOLMOD/Utility/cholmod_hypot', ...
    '../../CHOLMOD/Utility/cholmod_malloc', ...
    '../../CHOLMOD/Utility/cholmod_maxrank', ...
    '../../CHOLMOD/Utility/cholmod_mult_size_t', ...
    '../../CHOLMOD/Utility/cholmod_nnz', ...
    '../../CHOLMOD/Utility/cholmod_ones', ...
    '../../CHOLMOD/Utility/cholmod_pack_factor', ...
    '../../CHOLMOD/Utility/cholmod_ptranspose', ...
    '../../CHOLMOD/Utility/cholmod_realloc', ...
    '../../CHOLMOD/Utility/cholmod_realloc_multiple', ...
    '../../CHOLMOD/Utility/cholmod_reallocate_column', ...
    '../../CHOLMOD/Utility/cholmod_reallocate_factor', ...
    '../../CHOLMOD/Utility/cholmod_reallocate_sparse', ...
    '../../CHOLMOD/Utility/cholmod_reallocate_triplet', ...
    '../../CHOLMOD/Utility/cholmod_sbound', ...
    '../../CHOLMOD/Utility/cholmod_score_comp', ...
    '../../CHOLMOD/Utility/cholmod_set_empty', ...
    '../../CHOLMOD/Utility/cholmod_sort', ...
    '../../CHOLMOD/Utility/cholmod_sparse_to_dense', ...
    '../../CHOLMOD/Utility/cholmod_sparse_to_triplet', ...
    '../../CHOLMOD/Utility/cholmod_speye', ...
    '../../CHOLMOD/Utility/cholmod_spzeros', ...
    '../../CHOLMOD/Utility/cholmod_start', ...
    '../../CHOLMOD/Utility/cholmod_transpose', ...
    '../../CHOLMOD/Utility/cholmod_transpose_sym', ...
    '../../CHOLMOD/Utility/cholmod_transpose_unsym', ...
    '../../CHOLMOD/Utility/cholmod_triplet_to_sparse', ...
    '../../CHOLMOD/Utility/cholmod_version', ...
    '../../CHOLMOD/Utility/cholmod_xtype', ...
    '../../CHOLMOD/Utility/cholmod_zeros', ...
    '../../CHOLMOD/Check/cholmod_check', ...
    '../../CHOLMOD/Check/cholmod_read', ...
    '../../CHOLMOD/Check/cholmod_write', ...
    '../../CHOLMOD/Cholesky/cholmod_amd', ...
    '../../CHOLMOD/Cholesky/cholmod_analyze', ...
    '../../CHOLMOD/Cholesky/cholmod_colamd', ...
    '../../CHOLMOD/Cholesky/cholmod_etree', ...
    '../../CHOLMOD/Cholesky/cholmod_factorize', ...
    '../../CHOLMOD/Cholesky/cholmod_postorder', ...
    '../../CHOLMOD/Cholesky/cholmod_rcond', ...
    '../../CHOLMOD/Cholesky/cholmod_resymbol', ...
    '../../CHOLMOD/Cholesky/cholmod_rowcolcounts', ...
    '../../CHOLMOD/Cholesky/cholmod_rowfac', ...
    '../../CHOLMOD/Cholesky/cholmod_solve', ...
    '../../CHOLMOD/Cholesky/cholmod_spsolve', ...
    '../../CHOLMOD/Supernodal/cholmod_super_numeric', ...
    '../../CHOLMOD/Supernodal/cholmod_super_solve', ...
    '../../CHOLMOD/Supernodal/cholmod_super_symbolic' } ;

cholmod_c_partition_src = {
    '../../CHOLMOD/Partition/cholmod_l_ccolamd', ...
    '../../CHOLMOD/Partition/cholmod_l_csymamd', ...
    '../../CHOLMOD/Partition/cholmod_l_camd', ...
    '../../CHOLMOD/Partition/cholmod_metis_wrapper', ...
    '../../CHOLMOD/Partition/cholmod_l_metis', ...
    '../../CHOLMOD/Partition/cholmod_l_nesdis', ...
    '../../CHOLMOD/Partition/cholmod_ccolamd', ...
    '../../CHOLMOD/Partition/cholmod_csymamd', ...
    '../../CHOLMOD/Partition/cholmod_camd', ...
    '../../CHOLMOD/Partition/cholmod_metis', ...
    '../../CHOLMOD/Partition/cholmod_nesdis' } ;

% SuiteSparseQR does not need the MatrixOps or Modify modules of CHOLMOD
%   cholmod_unused = {
%       '../../CHOLMOD/MatrixOps/cholmod_l_drop', ...
%       '../../CHOLMOD/MatrixOps/cholmod_l_horzcat', ...
%       '../../CHOLMOD/MatrixOps/cholmod_l_norm', ...
%       '../../CHOLMOD/MatrixOps/cholmod_l_scale', ...
%       '../../CHOLMOD/MatrixOps/cholmod_l_sdmult', ...
%       '../../CHOLMOD/MatrixOps/cholmod_l_ssmult', ...
%       '../../CHOLMOD/MatrixOps/cholmod_l_submatrix', ...
%       '../../CHOLMOD/MatrixOps/cholmod_l_vertcat', ...
%       '../../CHOLMOD/MatrixOps/cholmod_l_symmetry', ...
%       '../../CHOLMOD/Modify/cholmod_l_rowadd', ...
%       '../../CHOLMOD/Modify/cholmod_l_rowdel', ...
%       '../../CHOLMOD/Modify/cholmod_l_updown' } ;

% SuiteSparseQR source code, and mex support file
spqr_cpp_src = {
    '../Source/spqr_parallel', ...
    '../Source/spqr_1colamd', ...
    '../Source/spqr_1factor', ...
    '../Source/spqr_1fixed', ...
    '../Source/spqr_analyze', ...
    '../Source/spqr_append', ...
    '../Source/spqr_assemble', ...
    '../Source/spqr_cpack', ...
    '../Source/spqr_csize', ...
    '../Source/spqr_cumsum', ...
    '../Source/spqr_debug', ...
    '../Source/spqr_factorize', ...
    '../Source/spqr_fcsize', ...
    '../Source/spqr_freefac', ...
    '../Source/spqr_freenum', ...
    '../Source/spqr_freesym', ...
    '../Source/spqr_front', ...
    '../Source/spqr_fsize', ...
    '../Source/spqr_happly', ...
    '../Source/spqr_happly_work', ...
    '../Source/spqr_hpinv', ...
    '../Source/spqr_kernel', ...
    '../Source/spqr_larftb', ...
    '../Source/spqr_panel', ...
    '../Source/spqr_rconvert', ...
    '../Source/spqr_rcount', ...
    '../Source/spqr_rhpack', ...
    '../Source/spqr_rmap', ...
    '../Source/spqr_rsolve', ...
    '../Source/spqr_shift', ...
    '../Source/spqr_stranspose1', ...
    '../Source/spqr_stranspose2', ...
    '../Source/spqr_trapezoidal', ...
    '../Source/spqr_type', ...
    '../Source/spqr_tol', ...
    '../Source/spqr_maxcolnorm', ...
    '../Source/SuiteSparseQR_qmult', ...
    '../Source/SuiteSparseQR', ...
    '../Source/SuiteSparseQR_expert', ...
    '../Source/spqr_cholmod_wrappers', ...
    '../MATLAB/spqr_mx' } ;

% SuiteSparse C source code, for MATLAB error handling
spqr_c_mx_src = { '../MATLAB/spqr_mx_error' } ;

% SuiteSparseQR mexFunctions
spqr_mex_cpp_src = { 'spqr', 'spqr_qmult', 'spqr_solve', 'spqr_singletons' } ;

if (ispc)
    obj_extension = '.obj' ;
else
    obj_extension = '.o' ;
end

% compile each library source file
obj = '' ;

c_source = [config_src amd_c_src colamd_c_src cholmod_c_src spqr_c_mx_src ] ;
c_source = [c_source cholmod_c_partition_src ccolamd_c_src camd_c_src ] ;

cpp_source = spqr_cpp_src ;

kk = 0 ;

for f = cpp_source
    ff = f {1} ;
    slash = strfind (ff, '/') ;
    if (isempty (slash))
        slash = 1 ;
    else
        slash = slash (end) + 1 ;
    end
    o = ff (slash:end) ;
    obj = [obj  ' ' o obj_extension] ;                                      %#ok
    s = sprintf ('mex %s -O %s -c %s.cpp', flags, include, ff) ;
    kk = do_cmd (s, kk, details) ;
end

for f = c_source
    ff = f {1} ;
    slash = strfind (ff, '/') ;
    if (isempty (slash))
        slash = 1 ;
    else
        slash = slash (end) + 1 ;
    end
    o = ff (slash:end) ;
    % fprintf ('%s\n', o) ;
    o = [o obj_extension] ;
    obj = [obj  ' ' o] ;					            %#ok
    s = sprintf ('mex %s -O %s -c %s.c', flags, include, ff) ;
    kk = do_cmd (s, kk, details) ;
end


% compile each mexFunction
for f = spqr_mex_cpp_src
    s = sprintf ('mex %s -O %s %s.cpp', flags, include, f{1}) ;
    s = [s obj ' ' lib] ;                                                   %#ok
    kk = do_cmd (s, kk, details) ;
end

% clean up
s = ['delete ' obj] ;
status = warning ('off', 'MATLAB:DELETE:FileNotFound') ;
delete rename.h
warning (status) ;
do_cmd (s, kk, details) ;
fprintf ('\nSuiteSparseQR successfully compiled\n') ;

%-------------------------------------------------------------------------------
function kk = do_cmd (s, kk, details)
%DO_CMD evaluate a command, and either print it or print a "."
if (details)
    fprintf ('%s\n', s) ;
else
    if (mod (kk, 60) == 0)
        fprintf ('\n') ;
    end
    kk = kk + 1 ;
    fprintf ('.') ;
end
eval (s) ;

